package org.glorylight.hacks.social.model;

import java.io.Serializable;
import java.sql.Blob;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;

import org.hibernate.annotations.Type;

@Entity
@Table(name = "user", uniqueConstraints = @UniqueConstraint(columnNames = { "userId" }))
@NamedQueries({ @NamedQuery(name = "user-by-userid", query = "from User a where a.userId = :userId")})
//@Cacheable
//@Cache(region = "users", )
public class User implements Serializable {

	private static final long serialVersionUID = 7840802631494387703L;

	@Id
	@Column(name = "email_address")
	private String emailAddress;

	@Column
	private Byte[] password;

	@Column(name = "firstName", nullable = false, length = 50)
	private String firstName;

	@Column(name = "lastName", nullable = false, length = 50)
	private String lastName;

	@Temporal(TemporalType.DATE)
	@Column(name = "birth_date")
	private Date birthDate;

	@Column(name = "gender", length = 10)
	private String gender;

	@Column(name = "mobile_no", length = 25)
	private String mobileNo;

	@Column(name = "timeline")
	private Blob timeline;

	@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	private List<UserNetwork> networks = new ArrayList<UserNetwork>();

	@OneToMany(mappedBy = "id.user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
	private List<UserRole> roles = new ArrayList<UserRole>();

	@Column(name = "babyName", length = 50)
	private String babyName;

	@Temporal(TemporalType.DATE)
	@Column(name = "babyBirthDate")
	private Date babyBirthDate;

	@Temporal(TemporalType.TIMESTAMP)
	@Column
	private Date registrationDate;

	@Column(nullable = false, columnDefinition = "boolean default false")
	private Boolean activate;

	@Type(type = "uuid")
	@Column(length = 32)
	private UUID userId;

	public User() {
	}

	public User(String emailAddress, Byte[] password, String firstName,
			String lastName, Date birth, String gender, String mobileNo,
			Date registrationDate, Boolean activate) {
		this.emailAddress = emailAddress;
		this.password = password;
		this.firstName = firstName;
		this.lastName = lastName;
		this.birthDate = birth;
		this.gender = gender;
		this.mobileNo = mobileNo;
		// assign automatic userid
		this.userId = UUID.randomUUID();
		this.registrationDate = registrationDate;
		this.activate = activate;
	}

	public String getEmailAddress() {
		return emailAddress;
	}

	public void setEmailAddress(String emailAddress) {
		this.emailAddress = emailAddress;
	}

	public Byte[] getPassword() {
		return password;
	}

	public void setPassword(Byte[] password) {
		this.password = password;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public Date getBirthDate() {
		return birthDate;
	}

	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public Blob getTimeline() {
		return timeline;
	}

	public void setTimeline(Blob timeline) {
		this.timeline = timeline;
	}

	public List<UserNetwork> getNetworks() {
		return networks;
	}

	public void setNetworks(List<UserNetwork> networks) {
		this.networks = networks;
	}

	public String getMobileNo() {
		return mobileNo;
	}

	public void setMobileNo(String mobileNo) {
		this.mobileNo = mobileNo;
	}

	public String getBabyName() {
		return babyName;
	}

	public void setBabyName(String babyName) {
		this.babyName = babyName;
	}

	public Date getBabyBirthDate() {
		return babyBirthDate;
	}

	public void setBabyBirthDate(Date babyBirthDate) {
		this.babyBirthDate = babyBirthDate;
	}

	public UUID getUserId() {
		return userId;
	}

	public void setUserId(UUID userId) {
		this.userId = userId;
	}

	public List<UserRole> getRoles() {
		return roles;
	}

	public void setRoles(List<UserRole> roles) {
		this.roles = roles;
	}

	public Date getRegistrationDate() {
		return registrationDate;
	}

	public void setRegistrationDate(Date registrationDate) {
		this.registrationDate = registrationDate;
	}

	public boolean isActivated() {
		return activate;
	}

	public void setActivate(boolean activate) {
		this.activate = activate;
	}

}
